$.extend(ksg.ui, /** @lends ksg.ui */{

	/**
	* @namespace
	* Action availability enum used by bizproc actions to indicate their current state for user interaction.
	* @meta-type enum
	*/
	Availability: {
		/**The given value is not set. */
		NotSet: -1, 
		/** The user has no access */
		None: 0,
		/** The user has access, but not at this moment due to other reasons like the current UI state. */
		Disabled: 1, 
		/** The user has access and can use the action right now */
		Enabled: 2
	},
	
	/**
	* @namespace
	* The base.bizproc expects the views it is interacting with to specify what type of view they are
	* for this bizproc.
	* @meta-type enum
	*/
	BizProcWidgetType: {
		/** A bizobj list display, meant to show the primary list of bizobjs from a bizproc  */
		List: 0,
		/** A bizobj detail display, meant to show the details on one bizobj, typically the current bizobj from the bizproc  */
		Disp: 1,
		/** A filter/sort criteria display, meant to help build the filter/sort options for getting the list of bizobjs */
		Criteria: 2,
		/** A paging display that will allow the user to page through the main list of bizobjs when they can only see a small number of them at one time */
		Pager: 3,
		/** An action trigger widget that will typically respond to user interaction (such as mouse click) and then trigger an action on the bizproc */
		ActionTrigger: 4,
		/** To be documented */
		AltList: 5,
		/** To be documented */
		AltDisp: 6, 
		/** To be documented */
		AltDisp2: 7,
		/** Some other custom widget that the particular bizproc would know how to deal with */
		Other: 8
	},

	/**
	* @namespace
	* The ksg.ui.BizProc class can use a blend of two bizobj lists, one being a master list
	* and the other being the main list, using this enum to indicate how it is getting its
	* master bizobj list.
	* @meta-type enum
	*/
	MasterDataOption: {
		/** Not specified */
		Unknown: -1,
		/** There is no master bizobj list */
		None: 0, 
		/** There is a master bizobj list, which comes from a parent bizproc's data */
		ListFromParentBizProc: 1, 
		/** There is a master bizobj list, which is retrieved by calling the bizrule named in the bizproc's bizrules.getMasterBizObjListBizRule */
		ListFromRule: 2
	},
	
	//Will get reset to true after the page load event has fired.  Can be used to determine if the page has loaded yet.
	pageLoaded: false,
	
	/**
	* A collection of objects that can get/set values out of a dom element.  This is an important class
	* for moving data between a dom element tree and a bizobj.
	*
	* @type Map<string,object> 
	*/
	fields: {
		"label": {
			//getVal on label returns null because it is a read only control.
			getVal: function ($el) { return null; },
			setVal: function ($el, val) { $el.html(val); }
		},
		"textbox": {
			getVal: function ($el) { return $el.val(); },
			setVal: function ($el, val) { $el.val(val); }
		},
		"textarea": {
			getVal: function ($el) { return $el.val(); },
			setVal: function ($el, val) { $el.val(val); }
		},
		"hiddenfield": {
			getVal: function ($el) { return $el.val(); },
			setVal: function ($el, val) { $el.val(val); }
		},
		"checkbox": {
			getVal: function ($el) { return $el.attr('checked') ? 'True' : 'False'; },
			setVal: function ($el, val) { $el.attr('checked', val.toLowerCase() == 'true' ? true : false); }
		},
		"dropdowncalendar": {
			getVal: function ($el) { return $('#' + $el.attr('id') + 'Fld').val(); },
			setVal: function ($el, val) { $('#' + $el.attr('id') + 'Fld').val(val); }
		},
		"combo": {
			getVal: function ($el) { 
				var v = $('#' + $el.attr('id') + 'SelectedValue0').val(); 
				return v;
			},
			setVal: function ($el, val) { 
				var cb = nitobi.getComponent($el.attr('id'));
				setComboSelectedRowByKey(cb, val); 
			}
		},
		"combosearch": {
			getVal: function($el) {
				var v = $ntb($el.attr('id') + 'SelectedValue0').value;//var v2 = $ntb('EBAComboBoxTextValue' + $el.attr('id')).value;if(v2=='' || v=='') v = v2;
				return v==""?null:v;
			},
			setVal: function ($el, val) { 
				var cb = nitobi.getComponent($el.attr('id'));
				setComboSelectedRowByKey(cb, val); 
			}
		},
		"dropdownlist": {
			getVal: function ($el) { var el = $el.get(0); return el.options(el.selectedIndex).value; },
			setVal: function ($el, val) { var dd = $el.get(0); for (var p = 0; p < dd.options.length; p++) if (dd.options[p].value == val) { { dd.options[p].selected = true; break; } }; }
		},
		"radiobutton": {
			getVal: function ($el) { return $el.checked ? 'True' : 'False'; },
			setVal: function ($el, val) { $el.attr('checked', val.toLowerCase() == 'true' ? true : false); }
		},
		"editableimage": {
			getVal: function ($el) {
				return getScsImageSrc($el,false);
			},
			setVal: function ($el, val) { $el.attr('src', val); }
		},
		"image": {
			getVal: function ($el) { return $el.attr('src'); },
			setVal: function ($el, val) { $el.attr('src', val); }
		},
		"hyperlink": {
			getVal: function ($el) { return $el.attr('href'); },
			setVal: function ($el, val) { $el.attr('href', val); }
		},
		"ckeditor": {
			getVal: function ($el) { try{
				var v = CKEDITOR.instances[$el.attr('id')].getData();
				return v;
			}catch(e){} },
			setVal: function ($el, val) { try{var f = CKEDITOR.instances[$el.attr('id')];if(f!=null)f.setData(val);}catch(e){} }
		},
		"readonlytext": {
			//Even though the control is named readonlytext, it is actually not read only and can be edited.
			getVal: function ($el) { return getROCTextValue($el); },
			setVal: function ($el, val) {
				$el.html(val);

				//TODO: Move the following out of here and into another control called 'scriptablereadonlytext'
				var re = /<script\b[\s\S]*?>([\s\S]*?)<\//ig;
				var match;
				while (match = re.exec(val)) {
					eval(match[1]);
				}
			}
		}
	},

	/**
	* @namespace
	* Objects that represent widget prototypes are defined in here.  This helps with "widget inheritance".
	* @meta-type namespace
	*/
	widgets: {},
	/**
	* @namespace
	* The widget map is a collection of functions that know how to create a specific type of widget.
	* The keys in this colleciton map to the css class names attached to dom elements.  This
	* is the key class factory used by the scsSetupUI jQuery plugin.
	* @meta-type factory
	*/
	widgetMap: {
		addWidget: function(widgetId, factoryMethod) {this[widgetId] = factoryMethod;}
	},

	/**
	* This will look for all elements marked as an edit field and get its value if it is marked as
	* being edited.  The resulting obj will be populated with the values from the dirty elements
	* only.
	*/
	populateFromDirtyFields: function ($el, obj) {
		$el.find(".ksg-edit-field").each(function () {
		});
	},

	_tmplCache: {},
	
	getTemplate: function (templateName, ext, success, error) {
		var $tmpl = null;
		var rtId = templateName+ext;
		var $tmpl = ksg.ui._tmplCache[rtId];
		if ((!($tmpl) || $tmpl.length == 0) && templateName) {
			ksg.services.getTemplate(rtId, function(tmpl) {
				var $tmpl = $(tmpl.response);
				ksg.ui._tmplCache[rtId] = $tmpl;
				success({tmpl: $tmpl});
			}, error);
		}
		else if ($tmpl.length !=0)
			success({ tmpl: $tmpl });
		//TODO:ERROR OTHERWISE
	},

	/**
	* Will break aparet the window.location value and grab at the query string parameters.
	* Returns an object with the results.
	* Note: This implementation does not deal with multiple names with the same name, which is valid.
	*/
	queryString: function () {
		if (this._urlParams == null) {
			this._urlParams = {};
			var e,
			a = /\+/g,  // Regex for replacing addition symbol with a space
			r = /([^&=]+)=?([^&]*)/g,
			d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
			q = window.location.search.substring(1);

			while (e = r.exec(q))
				this._urlParams[d(e[1])] = d(e[2]);
		}
		return this._urlParams;
	},
	_urlParams: null,

	loadCssUrl: function (url) {
		$("head").append($("<link>").attr({ type: 'text/css', rel: 'stylesheet', href: url }));
	},
	loadScriptUrl: function (url, success) {
		$.getScript(url, success);
	},
	
	getElementDataObject: function($el, name) {
		var op = $el.data(name);
		var opt = typeof(op);
		if(opt == "string")
			op = $.parseJSON(opt);
		return op;
	}
});
